# 文件名：models.py
# 作者：系统自动生成
# 创建日期：2025-04-26
# 描述：学生管理应用的数据模型文件，定义学生信息、考勤记录等数据库表结构

from django.db import models
from django.contrib.auth.models import User

from django.core.validators import RegexValidator

class Student(models.Model):
    """
    学生信息模型
    
    属性：
        user - 关联的用户账号
        name - 学生姓名
        student_id - 学号(12位数字)
        auxiliary_id - 学籍辅号(12位数字)
        class_info - 学籍班级(入学年份+班级)
        national_id - 全国学籍号(GL+身份证号)
        current_class - 当前班级
        campus - 所属校区
        enrollment_year - 入学年份
        graduation_year - 毕业年份
        gender - 性别
        birth_date - 出生日期(自动从身份证号提取)
        id_card - 身份证号
        ethnicity - 民族
        home_address - 家庭住址
        registered_address - 户口所在地
        contact1_name - 联系人1姓名
        contact1_relation - 联系人1关系
        contact1_phone - 联系人1电话
        contact2_name - 联系人2姓名
        contact2_relation - 联系人2关系
        contact2_phone - 联系人2电话
        registration_type - 注册类型
        current_status - 当前状态
        remark - 备注
        is_special_family - 特殊家庭学生
        is_special_physique - 特异体质学生
        is_psychological_abnormal - 心理异常学生
        is_left_behind - 留守儿童
    """
    GENDER_CHOICES = [
        ('M', '男'),
        ('F', '女'),
    ]
    
    REGISTRATION_TYPE_CHOICES = [
        ('registered', '在籍'),
        ('transferred_in', '学籍转入'),
        ('temporary', '借读'),
    ]
    
    CURRENT_STATUS_CHOICES = [
        ('studying', '在读'),
        ('suspended', '休学'),
        ('temporary_out', '在外借读'),
        ('dropped_out', '退学'),
        ('transferred_out', '学籍转出'),
    ]
    
    RELATION_CHOICES = [
        ('father', '父亲'),
        ('mother', '母亲'),
        ('grandfather', '爷爷'),
        ('grandmother', '奶奶'),
        ('maternal_grandfather', '姥爷'),
        ('maternal_grandmother', '姥姥'),
        ('other', '其他'),
    ]
    
    SPECIAL_FAMILY_CHOICES = [
        ('none', '否'),
        ('divorced', '离异'),
        ('single_parent', '单亲'),
        ('poor', '贫困家庭'),
    ]
    
    # 学籍基本信息
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='student')
    student_id = models.CharField('学号', max_length=12, unique=True, validators=[RegexValidator(r'^\d{12}$', '学号必须是12位数字')])
    auxiliary_id = models.CharField('学籍辅号', max_length=12, blank=True, null=True, validators=[RegexValidator(r'^\d{12}$', '学籍辅号必须是12位数字')], help_text='默认与学号相同')
    class_info = models.CharField('学籍班级', max_length=50, help_text='格式：入学年份+班级，如2025级一班')
    national_id = models.CharField('全国学籍号', max_length=20, help_text='格式：GL+身份证号')
    current_class = models.CharField('当前班级', max_length=50)
    campus = models.ForeignKey('campus.Campus', on_delete=models.PROTECT, verbose_name='所属校区')
    enrollment_year = models.IntegerField('入学年份')
    graduation_year = models.IntegerField('毕业年份')
    
    # 学生基本信息
    name = models.CharField('姓名', max_length=50)
    gender = models.CharField('性别', max_length=1, choices=GENDER_CHOICES)
    birth_date = models.DateField('出生日期', null=True, blank=True)
    id_card = models.CharField('身份证号', max_length=18, validators=[RegexValidator(r'^\d{17}[0-9X]$', '请输入有效的身份证号')])
    ethnicity = models.CharField('民族', max_length=20)
    
    # 学生联系信息
    home_address = models.CharField('家庭住址', max_length=200)
    registered_address = models.CharField('户口所在地', max_length=200)
    contact1_name = models.CharField('联系人1姓名', max_length=50)
    contact1_relation = models.CharField('联系人1关系', max_length=30, choices=RELATION_CHOICES)
    contact1_phone = models.CharField('联系人1电话', max_length=20)
    contact2_name = models.CharField('联系人2姓名', max_length=50, blank=True, null=True)
    contact2_relation = models.CharField('联系人2关系', max_length=30, blank=True, null=True, choices=RELATION_CHOICES)
    contact2_phone = models.CharField('联系人2电话', max_length=20, blank=True, null=True)
    
    # 学生状态信息
    registration_type = models.CharField('注册类型', max_length=20, choices=REGISTRATION_TYPE_CHOICES, default='registered')
    current_status = models.CharField('当前状态', max_length=20, choices=CURRENT_STATUS_CHOICES, default='studying')
    remark = models.TextField('备注', blank=True, null=True)
    
    # 特殊信息标签
    is_special_family = models.CharField('特殊家庭学生', max_length=20, choices=SPECIAL_FAMILY_CHOICES, default='none')
    is_special_physique = models.BooleanField('特异体质学生', default=False)
    is_psychological_abnormal = models.BooleanField('心理异常学生', default=False)
    is_left_behind = models.BooleanField('留守儿童', default=False)
    
    def __str__(self):
        return f'{self.name}({self.student_id})'

class Attendance(models.Model):
    """
    学生考勤记录模型
    
    属性：
        student - 关联的学生
        date - 考勤日期
        status - 考勤状态
        leave_application - 关联的请假申请
        remark - 备注
    """
    STATUS_CHOICES = [
        ('present', '出勤'),
        ('late', '迟到'),
        ('absent', '缺勤'),
        ('leave', '请假'),
    ]
    
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='attendances')
    date = models.DateField('考勤日期')
    status = models.CharField('考勤状态', max_length=20, choices=STATUS_CHOICES)
    leave_application = models.ForeignKey('LeaveApplication', on_delete=models.SET_NULL, null=True, blank=True, related_name='attendances')
    remark = models.TextField('备注', blank=True)
    
    def __str__(self):
        return f'{self.student.name} - {self.date} - {self.status}'
        
    def save(self, *args, **kwargs):
        """
        重写save方法，当考勤状态为请假时自动关联请假申请
        """
        if self.status == 'leave' and not self.leave_application:
            # 查找该学生在该日期的请假申请
            leave = LeaveApplication.objects.filter(
                student=self.student,
                start_date__lte=self.date,
                end_date__gte=self.date,
                status='approved'
            ).first()
            if leave:
                self.leave_application = leave
        super().save(*args, **kwargs)

class StudentChangeLog(models.Model):
    """
    学生信息变更记录模型
    
    属性：
        student - 关联的学生
        changed_by - 变更人
        changed_at - 变更时间
        change_field - 变更字段
        old_value - 旧值
        new_value - 新值
        change_reason - 变更原因
    """
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='change_logs')
    changed_by = models.CharField('变更人', max_length=100)
    changed_at = models.DateTimeField('变更时间', auto_now_add=True)
    change_field = models.CharField('变更字段', max_length=50)
    old_value = models.TextField('旧值', blank=True, null=True)
    new_value = models.TextField('新值', blank=True, null=True)
    change_reason = models.TextField('变更原因', blank=True, null=True)
    
    def __str__(self):
        return f'{self.student.name} - {self.change_field} - {self.changed_at}'

class Grade(models.Model):
    """
    学生成绩记录模型
    
    属性：
        student - 关联的学生
        course - 课程名称
        score - 分数
        semester - 学期
        exam_date - 考试日期
        teacher - 授课教师
        remark - 备注
    """
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='grades')
    course = models.CharField('课程名称', max_length=50)
    score = models.DecimalField('分数', max_digits=5, decimal_places=2)
    semester = models.CharField('学期', max_length=20)
    exam_date = models.DateField('考试日期')
    teacher = models.CharField('授课教师', max_length=50)
    remark = models.TextField('备注', blank=True)
    
    def __str__(self):
        return f'{self.student.name} - {self.course}: {self.score}'

class LeaveApplication(models.Model):
    """
    学生请假申请模型
    
    属性：
        student - 关联的学生
        applicant - 申请人(家长或老师)
        start_date - 请假开始日期
        end_date - 请假结束日期
        reason - 请假原因
        duration - 请假时长(天)
        contact_person - 对接人姓名
        contact_phone - 对接人电话
        proof_material - 证明材料路径
        status - 审批状态
        approver - 审批人
        approved_at - 审批时间
        remark - 备注
    """
    STATUS_CHOICES = [
        ('pending', '待审批'),
        ('approved', '已批准'),
        ('rejected', '已拒绝'),
    ]
    
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='leave_applications')
    applicant = models.ForeignKey(User, on_delete=models.CASCADE, related_name='submitted_leaves')
    start_date = models.DateField('请假开始日期')
    end_date = models.DateField('请假结束日期')
    reason = models.TextField('请假原因')
    duration = models.PositiveIntegerField('请假时长(天)')
    contact_person = models.CharField('对接人姓名', max_length=50)
    contact_phone = models.CharField('对接人电话', max_length=20)
    proof_material = models.FileField('证明材料', upload_to='leave_proofs/', blank=True, null=True)
    status = models.CharField('审批状态', max_length=20, choices=STATUS_CHOICES, default='pending')
    approver = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='approved_leaves')
    approved_at = models.DateTimeField('审批时间', null=True, blank=True)
    remark = models.TextField('备注', blank=True)
    
    def __str__(self):
        return f'{self.student.name}的请假申请({self.start_date}至{self.end_date})'


class SpecialStudentInfo(models.Model):
    """
    特殊学生信息表
    
    属性：
        student - 关联的学生(学号)
        special_type - 特殊类型(1:残疾,2:贫困,3:留守,4:单亲,5:其他)
        description - 详细描述
        preventive_measures - 帮扶措施
        status - 状态(0:已解决,1:帮扶中)
    """
    SPECIAL_TYPE_CHOICES = [
        (1, '残疾'),
        (2, '贫困'),
        (3, '留守'),
        (4, '单亲'),
        (5, '其他')
    ]
    
    STATUS_CHOICES = [
        (0, '已解决'),
        (1, '帮扶中')
    ]
    
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='special_infos')
    special_type = models.SmallIntegerField('特殊类型', choices=SPECIAL_TYPE_CHOICES)
    description = models.TextField('情况说明', help_text='详细描述学生的特殊情况')
    preventive_measures = models.TextField('帮扶措施', help_text='针对该学生的特殊帮扶措施')
    status = models.SmallIntegerField('状态', choices=STATUS_CHOICES, default=1)
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)
    
    
    
    def __str__(self):
        return f'{self.student.name}的特殊信息'

class StudentSupport(models.Model):
    """
    帮扶记录表
    
    属性：
        student - 关联的学生
        support_type - 帮扶类型
        support_content - 帮扶内容
        support_date - 帮扶日期
        supporter - 帮扶人
        result - 帮扶结果
        remark - 备注
    """
    student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='supports')
    support_type = models.CharField('帮扶类型', max_length=50)
    support_content = models.TextField('帮扶内容')
    support_date = models.DateField('帮扶日期')
    supporter = models.CharField('帮扶人', max_length=50)
    result = models.TextField('帮扶结果', blank=True)
    remark = models.TextField('备注', blank=True)
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)
    
    def __str__(self):
        return f'{self.supporter}对{self.student.name}的帮扶记录'